package com.hb.repository;

import com.hb.model.Order;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;

import java.util.List;

/**
 * 与其他的 Spring Data 项目一样，Spring Data Neo4j 会为扩展 Repository 接口的其他接口生成 Repository 方法实现。在本例中，OrderRepository
 * 扩展了 GraphRepository，而后者又间接扩展了 Repository 接口。因此，Spring Data Neo4j 将会在运行时创建 OrderRepository 的实现。
 * 注意，GraphRepository 使用 Order 进行了参数化，也就是这个 Repository 所要使用的实体类型。因为 Neo4j 要求图 ID 的类型为 Long，因此在扩展
 * GraphRepository 的时候，没有必要再去指定 ID 类型。
 * 现在，我们就能够使用很多通用的 CRUD 操作，这与 JpaRepository 和 MongoRepository 所提供的功能类似。下面描述了扩展 GraphRepository 所能够得到的方法。
 * 1、long count();返回在数据库中，目标类型有多少实体
 * 2、void delete(Iterable<？ extends T>);删除多个实体
 * 3、void delete(Long id);根据 ID，删除一个实体
 * 4、void delete(T);删除一个实体
 * 5、void deleteAll();删除目标类型的所有实体
 * 6、boolean exists(Long id);根据指定的 ID，检查实体是否存在
 * 7、EndResult<T> findAll();获取目标类型的所有实体
 * 8、Page<T> findAll(Pageable);返回目标类型分页和排序后的实体列表
 * 9、EndResult<T> findAll(Sort);返回目标类型排序后的实体列表
 * 10、EndResult<T> findAllBySchemaPropertyValue(String,Object);返回指定属性匹配给定值的所有实体
 * 11、Iterable<T> findAllByTraversal(N, TraversalDescription);返回从某个节点开始，图遍历到达的节
 * 12、T findBySchemaPropertyValue (String,Object);返回指定属性匹配给定值的一个实体
 * 13、T findOne(Long);根据 ID，获得某一个实体
 * 14、EndResult<T> query(String, Map<String,Object>);返回匹配给定 Cypher 查询的所有实体
 * 15、Iterable<T> save(Iterable<T>);保存多个实体
 * 16、S save(S);保存一个实体
 */
public interface OrderRepository extends GraphRepository<Order>, OrderOperations {
    /**
     * 按照命名约定使用Spring Data Neo4j 来添加自定义的查询方法
     * @param customer
     * @return
     */
    List<Order> findByCustomer(String customer);
    List<Order> findByCustomerAndType(String customer, String type);

    /**
     * 当命名约定无法满足需求时，我们还可以为方法添加 @Query 注解，为其指定自定义的查询。我们之前已经见过 @Query 注解。在 Spring Data JPA 中，
     * 我们使用它来为 Repository 方法指定 JPA 查询。在 Spring Data MongoDB 中，我们使用它来指定匹配 JSON 的查询。但是，在使用 Spring Data Neo4j 的时候，
     * 我们必须指定 Cypher 查询：
     * 在这里，findSiAOrders() 方法上使用了 @Query 注解，并设置了一个 Cypher 查询，它会查找与 Item 关联并且 product 属性等于 “Spring in Action” 的所有 Order 节点。
     * @return
     */
    @Query("match (o:Order)-[:HAS_ITEMS]->(i:Item) where i.product='Spring in Action' return o")
    List<Order> findSiAOrders();
}
